package org.asiainfo.system.service.impl;

import org.asiainfo.common.core.constant.CacheNames;
import org.asiainfo.common.core.exception.ServiceException;
import org.asiainfo.common.core.utils.StringUtils;
import org.asiainfo.common.mybatis.stream.core.page.TableDataInfo;
import org.asiainfo.common.mybatis.stream.core.page.PageQuery;
import org.asiainfo.common.redis.utils.CacheUtils;
import org.asiainfo.system.domain.vo.SysDictDataVo;
import org.asiainfo.system.domain.bo.SysDictDataBo;
import org.asiainfo.system.domain.SysDictData;
import org.asiainfo.system.service.SysDictDataService;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.asiainfo.common.core.utils.MapstructUtils;
import lombok.extern.slf4j.Slf4j;
import cn.hutool.core.util.ObjectUtil;
import com.mybatisflex.core.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.asiainfo.system.mapper.SysDictDataMapper;
import com.mybatisflex.core.paginate.Page;

import java.util.Map;
import java.util.Collection;
import java.util.List;

/**
 * 字典数据表(SysDictData)表服务实现类
 *
 * @author dotor-ww
 * @since 2024-01-19 22:37:49
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class SysDictDataServiceImpl extends ServiceImpl<SysDictDataMapper, SysDictData> implements SysDictDataService {

    /**
     * 构建查询条件
     *
     * @param sysDictDataBo 筛选条件
     * @return 查询结果
     */
    private QueryWrapper builderQueryWrapper(SysDictDataBo sysDictDataBo) {
        Map<String, Object> params = sysDictDataBo.getParams();
        QueryWrapper query = query();
        query.eq(SysDictData::getDictLabel, sysDictDataBo.getDictLabel(), StringUtils.isNotBlank(sysDictDataBo.getDictLabel()));
        query.eq(SysDictData::getDictType, sysDictDataBo.getDictType(), StringUtils.isNotBlank(sysDictDataBo.getDictType()));
        query.between(SysDictData::getCreateTime, params.get("beginTime"), params.get("endTime"),
            ObjectUtil.isNotNull(params.get("beginTime")) && ObjectUtil.isNotNull(params.get("endTime")));
        return query;
    }

    /**
     * 查询
     *
     * @param sysDictDataBo 筛选条件
     * @return 查询结果
     */
    @Override
    public List<SysDictDataVo> queryList(SysDictDataBo sysDictDataBo) {
        QueryWrapper query = builderQueryWrapper(sysDictDataBo);
        return listAs(query, SysDictDataVo.class);
    }

    /**
     * 通过dictCode查询单条数据
     *
     * @param dictCode 主键
     * @return 实例对象
     */
    @Override
    public SysDictDataVo queryById(Long dictCode) {
        return getOneAs(query().eq(SysDictData::getDictCode, dictCode), SysDictDataVo.class);
    }

    /**
     * 分页查询
     *
     * @param sysDictDataBo 筛选条件
     * @param pageQuery     分页对象
     * @return 查询结果
     */
    @Override
    public TableDataInfo<SysDictDataVo> queryPageList(SysDictDataBo sysDictDataBo, PageQuery pageQuery) {
        QueryWrapper query = builderQueryWrapper(sysDictDataBo);
        pageQuery.buildOrder(query);
        if (StringUtils.isBlank(pageQuery.getOrderBy())) {
            query.orderBy(SysDictData::getCreateTime);
        }
        Page<SysDictDataVo> page = pageAs(pageQuery.buildPage(), query, SysDictDataVo.class);
        return TableDataInfo.build(page);
    }

    /**
     * 新增数据
     *
     * @param sysDictDataBo 实例对象
     * @return 实例对象
     */
    @CachePut(cacheNames = CacheNames.SYS_DICT, key = "#sysDictDataBo.dictType")
    @Override
    public List<SysDictDataVo> insertByBo(SysDictDataBo sysDictDataBo) {
        SysDictData sysDictData = MapstructUtils.convert(sysDictDataBo, SysDictData.class);
        if (ObjectUtil.isNull(sysDictData)) {
            throw new ServiceException("解析参数失败");
        }
        if (save(sysDictData)) {
            return listAs(query().eq(SysDictData::getDictType, sysDictData.getDictType()), SysDictDataVo.class);
        }
        throw new ServiceException("插入数据失败");
    }

    /**
     * 修改数据
     *
     * @param sysDictDataBo 实例对象
     * @return 实例对象
     */
    @CachePut(cacheNames = CacheNames.SYS_DICT, key = "#sysDictDataBo.dictType")
    @Override
    public List<SysDictDataVo> updateByBo(SysDictDataBo sysDictDataBo) {
        SysDictData sysDictData = MapstructUtils.convert(sysDictDataBo, SysDictData.class);
        if (ObjectUtil.isNull(sysDictData)) {
            throw new ServiceException("解析参数失败");
        }
        if (updateById(sysDictData)) {
            return listAs(query().eq(SysDictData::getDictType, sysDictData.getDictType()), SysDictDataVo.class);
        }
        throw new ServiceException("修改数据失败");
    }

    /**
     * 批量删除字典数据信息
     *
     * @param dictCodes 主键
     * @return 是否成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> dictCodes) {
        List<Long> dictCodeList = dictCodes.stream().toList();
        List<SysDictData> sysDictData = list(query().in(SysDictData::getDictCode, dictCodeList));
        for (SysDictData dictData : sysDictData) {
            CacheUtils.evict(CacheNames.SYS_DICT, dictData.getDictType());
        }
        return removeByIds(dictCodes);
    }

    /**
     * 通过字典类型查询字典数据
     *
     * @param dictType 字典类型
     * @return 查询结果
     */
    @Cacheable(cacheNames = CacheNames.SYS_DICT, key = "#dictType")
    @Override
    public List<SysDictDataVo> selectDictDataByType(String dictType) {
        return listAs(query().eq(SysDictData::getDictType, dictType), SysDictDataVo.class);
    }
}
